<script setup>
import { provide, readonly, ref } from 'vue'
import { myInjectionKey } from '../utils/keys'
import { useMouse } from '../utils/mouse'
import Child from '../components/provideAndInject/Child.vue'
const message = ref('hello')
provide('message', message)

const location = ref('广州')
function updateLocation() {
  location.value = '北京'
}

provide('location', {
  location,
  updateLocation
})

// 如果你想确保提供的数据不能被注入方的组件更改，你可以使用 readonly() 来包装提供的值。
const count = ref(0)
// provide('read-only-count', readonly(count))
provide('read-only-count', count)

// 但如果你正在构建大型的应用，包含非常多的依赖提供，或者你正在编写提供给其他开发者使用的组件库，建议最好使用 Symbol 来作为注入名以避免潜在的冲突。
const symKeys01 = ref('myInjectionKey01')
// const symKeys02 = ref('myInjectionKey02')
console.log(myInjectionKey, 'provide')
provide(myInjectionKey, symKeys01)
// provide(myInjectionKey, symKeys02)

const { x, y } = useMouse()
</script>

<template>
  <div>
    <h3>依赖注入</h3>
    <p>provide 和 inject 可以帮助我们解决“prop 逐级透传”这一问题。</p>
    <p>一个父组件相对于其所有的后代组件，会作为<b>依赖提供者</b>。任何后代的组件树，无论层级有多深，都可以<b>注入</b>由父组件提供给整条链路的依赖。</p>
    <hr />
    <input type="text" v-model="message">
    <Child />
    <hr />
    <h3>组合式函数-鼠标跟踪器</h3>
    <div>Mouse position is at: {{ x }}, {{ y }}</div>
  </div>
</template>